package com.ptkc.utils;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import java.lang.reflect.Field;
import java.util.*;

/**
 * @author: Mr.Jiao
 * @date: 2018年09月30日
 */
public class DataConvert {

//    /**
//     * 转换
//     * @param valMap
//     * @param clazz
//     * @param <T>
//     * @return
//     */
//    public static<T> T convert(Map<String,String> valMap, Class<T> clazz) {
//        List<Field> fields = getFields(clazz);
//        StringBuilder sb = new StringBuilder("{");
//        if(valMap != null && valMap.size() > 0) {
//            for (Field field : fields) {
//                String dataKey = getDataKey(field);
//                String value = valMap.get(dataKey);
//                if (StringUtil.isEmpty(value)) {
//                    continue;
//                }
//                sb.append("\"").append(field.getName()).append("\":\"").append(StringEscapeUtils.escapeJava(value)).append("\",");
//            }
//        }
//        sb.append("}");
//        return JSON.parseObject(sb.toString(), clazz);
//    }

    /**
     * 转换
     * @param valMap
     * @param clazz
     * @param <T>
     * @return
     */
    public static<T> T convert(Map valMap, Class<T> clazz) {
        List<Field> fields = getFields(clazz);
        StringBuilder sb = new StringBuilder("{");
        if(valMap != null && valMap.size() > 0) {
            for (Field field : fields) {
                if(field == null){
                    continue;
                }
                DataColumn column = field.getAnnotation(DataColumn.class);
                if(column != null) {
                    if (column.ignore()) {
                        continue;
                    }
                }
                String key = null;
                Object value = null;
                if(column != null){
                    key = column.value();
                    if(StringUtil.isEmpty(key)){
                        key = field.getName();
                    }
                    value = valMap.get(key);
                    if(value == null || StringUtil.isEmpty(value.toString())){
                        continue;
                    }
                    if(!column.format().equals(DataFormat.class)){
                        try {
                            DataFormat dataFormat = column.format().newInstance();
                            value = dataFormat.format(value);
                        } catch (Exception e) {
                            e.printStackTrace();
                            continue;
                        }
                    }

                }else{
                    key = field.getName();
                    value = valMap.get(key);
                }
                if (value == null || StringUtil.isEmpty(value.toString())) {
                    continue;
                }
                sb.append("\"").append(field.getName()).append("\":\"").append(StringEscapeUtils.escapeJava(value.toString())).append("\",");
            }
        }
        sb.append("}");
        try{
            return JSON.parseObject(sb.toString(), clazz);
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }

    }

    private static String getDataKey(Field field){
        DataColumn column = field.getAnnotation(DataColumn.class);
        if(column == null){
            return null;
        }else if(column.ignore()){
            return null;
        }
        String key = column.value();
        if(StringUtil.isEmpty(key)){
            key = field.getName();
        }
        return key;
    }

    /**
     * 转义正则特殊字符 （$()*+.[]?\^{}
     * \\需要第一个替换，否则replace方法替换时会有逻辑bug
     */
    public static String makeQueryStringAllRegExp(String str) {
        if(StringUtils.isBlank(str)){
            return str;
        }
        return str.replace("\\", "\\\\").replace("*", "\\*")
                .replace("+", "\\+").replace("|", "\\|")
                .replace("{", "\\{").replace("}", "\\}")
                .replace("(", "\\(").replace(")", "\\)")
                .replace("^", "\\^").replace("$", "\\$")
                .replace("[", "\\[").replace("]", "\\]")
                .replace("?", "\\?").replace(",", "\\,")
                .replace(".", "\\.").replace("&", "\\&")
                .replace(">", "&gt;").replace("<", "&lt;")
                .replace(" ", "&nbsp;").replace("\"", "&quot;")
                .replace("\'", "&#39;").replace("\\", "\\\\")
                .replace("\n", "\\n").replace("\r", "\\r");
    }

    private static List<Field> getFields(Class clazz){
        List<Field> fields = new ArrayList<>();
        Field []declaredFields = clazz.getDeclaredFields();
        if(declaredFields != null){
            fields.addAll(Arrays.asList(declaredFields));
        }
        Class<?> superClass = clazz.getSuperclass();
        if(superClass != null) {
            List<Field> supporFields = getFields(superClass);
            fields.addAll(supporFields);
        }
        return fields;
    }

}
